package cn.bugstack.service.impl;

import cn.bugstack.domain.vo.WeixinTemplateMessageVO;
import cn.bugstack.domain.req.WeixinQrCodeReq;
import cn.bugstack.domain.res.WeixinQrCodeRes;
import cn.bugstack.domain.res.WeixinTokenRes;
import cn.bugstack.service.ILoginService;
import cn.bugstack.service.wexin.IWeixinApiService;
import com.google.common.cache.Cache;
import org.springframework.stereotype.Service;
import retrofit2.Call;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: 小新
 * @Date: 2025/3/18 9:18
 * @Description:
 * @Version: v1.0
 */
@Service
public class WeixinLoginServiceImpl implements ILoginService {


//    @Value("${weixin.config.app-id")
    private String appId="wx551623954826fac2";

//    @Value("${weixin.config.app-secret")
    private String appSecret="057c5392ce0c22736ea206b2af0d1b8c";


//    @Value("${weixin.config.template_id")
    private String template_id="wfbyW-n0yAoSHSaC5zjbf2Rx9DbCRch_hPIZ4XdRyqw";


    @Resource
    private Cache<String, String> weixinAccessToken;

    @Resource
    private Cache<String, String> openidToken;

    @Resource
    private IWeixinApiService weixinApiService;


    /**
     * 生成 ticket
     * @return
     * @throws Exception
     */
    @Override
    public String createQrCodeTicket() throws Exception {

        //1.获取 accessToken

        //1.1 获取缓存中的 accessToken
        String accessToken = weixinAccessToken.getIfPresent(appId);

        //1.2 如果缓存中没有，则从微信服务器获取
        if(accessToken == null){
            Call<WeixinTokenRes> call = weixinApiService.getToken("client_credential", appId, appSecret);
            WeixinTokenRes weixinTokenRes = call.execute().body();
            assert weixinTokenRes != null;
            accessToken = weixinTokenRes.getAccess_token();
            weixinAccessToken.put(appId, accessToken);
        }
        // 2. 生成 ticket
        WeixinQrCodeReq weixinQrCodeReq = WeixinQrCodeReq.builder()
                .expire_seconds(2592000)
                .action_name(WeixinQrCodeReq.ActionNameTypeVO.QR_SCENE.getCode())
                .action_info(WeixinQrCodeReq.ActionInfo.builder()
                        .scene(WeixinQrCodeReq.ActionInfo.Scene.builder()
                                .scene_id(100601)
                                .build())
                        .build())
                .build();

        Call<WeixinQrCodeRes> call = weixinApiService.createQrCode(accessToken, weixinQrCodeReq);
        WeixinQrCodeRes weixinQrCodeRes = call.execute().body();
        assert null != weixinQrCodeRes;
        return weixinQrCodeRes.getTicket();

    }


    /**
     * 确认登录
     * @param ticket
     * @return
     */
    @Override
    public String checkLogin(String ticket) {
        return openidToken.getIfPresent(ticket);
    }


    /**
     * 保存登录状态
     * @param ticket
     * @param openId
     * @throws IOException
     */

    @Override
    public void saveLoginState(String ticket, String openId) throws IOException {
       openidToken.put(ticket, openId);
        // 1. 获取 accessToken 【实际业务场景，按需处理下异常】
        String accessToken = weixinAccessToken.getIfPresent(appId);
        if (null == accessToken){
            Call<WeixinTokenRes> call = weixinApiService.getToken("client_credential", appId, appSecret);
            WeixinTokenRes weixinTokenRes = call.execute().body();
            assert weixinTokenRes != null;
            accessToken = weixinTokenRes.getAccess_token();
            // 2.放入缓存
            weixinAccessToken.put(appId, accessToken);
        }

        // 2. 发送模板消息
        Map<String, Map<String, String>> data = new HashMap<>();
        WeixinTemplateMessageVO.put(data, WeixinTemplateMessageVO.TemplateKey.USER, openId);

        WeixinTemplateMessageVO templateMessageDTO = new WeixinTemplateMessageVO(openId, template_id);
        templateMessageDTO.setUrl("https://gitee.com/liuxinzhistudy");
        templateMessageDTO.setData(data);

        Call<Void> call = weixinApiService.sendMessage(accessToken, templateMessageDTO);
        call.execute();

    }
}
